/* ConsolePane.java
 * Author: liuex
 * 2007-12-14 ����04:00:50
 *
 * Note: 
 */
package org.lex.swing.widgets.console;

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.Writer;

import javax.swing.AbstractAction;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

import org.lex.swing.widgets.console.demo.windows.CommandShell;

public class ConsoleEditor extends JTextPane {
	private CommandShell shell = null;
	private Writer stdOut = null;
	private Writer stdErr = null;
	private int lastPosition = 0;

	public ConsoleEditor() {
		super();
		this.initialize();
		this.configInputActionMap();
		this.appendStdin("");
	}

	public String getInput() {
		String input = "";
		int len = this.getDocument().getLength() - lastPosition;
		try {
			input = this.getText(lastPosition, len);
			this.lastPosition += len;
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		return input;
	}

	public void appendStdin(String text) {
		this.append(text, TextStyle.STDIN.getAttributeSet());
	}

	public void appendStdout(String text) {
		this.append(text, TextStyle.STDOUT.getAttributeSet());
	}

	public void appendStdErr(String text) {
		this.append(text, TextStyle.STDERR.getAttributeSet());
	}

	public void append(String text, AttributeSet a) {
		Document doc = this.getDocument();
		try {
			doc.insertString(doc.getLength(), text, a);
			int len = doc.getLength();
			this.setCaretPosition(len);
			this.lastPosition = len;
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
	}

	public void enterAction(ActionEvent e) {
		String input = this.getInput();
		try {
			shell.execute(input);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}

	private void initialize() {
		this.stdOut = new Writer() {
			@Override
			public void close() {
			}

			@Override
			public void flush() {
			}

			@Override
			public void write(char[] cbuf, int off, int len) {
				appendStdout(String.valueOf(cbuf, off, len));
			}
		};
		this.stdErr = new Writer() {
			@Override
			public void close() {
			}

			@Override
			public void flush() {
			}

			@Override
			public void write(char[] cbuf, int off, int len) {
				appendStdErr(String.valueOf(cbuf, off, len));
			}
		};
		try {
			this.shell = CommandShell.createShell(stdOut, stdErr);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void configInputActionMap() {
		this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
		this.getActionMap().put("enter", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				enterAction(e);
			}
		});
	}
}
